#include "Database.h"

static Database* mInstance = NULL;

void
Database::initialize( QObject* parent )
{
	if( !mInstance )
	{
		mInstance = new Database( parent );
	}
}

Database*
Database::instance()
{
	Q_ASSERT( mInstance != NULL );
	return mInstance;
}

Database::Database( QObject* parent )
: QObject( parent )
{
	mSQLDatabase = QSqlDatabase::addDatabase( "QSQLITE" );
    mSQLDatabase.setDatabaseName( "engrDatabase" );

	if( !mSQLDatabase.open() )
	{
		QMessageBox::critical( NULL, "ENGR Database", "Could not open the database" );
	}
	else
	{
		QSqlQuery query;

		// Semester
		
		query.exec( tr( "create table " ) +
			        PROGRAM + 
					tr( " (id int primary key, semester int, disipline varchar(20))" ) );
		
		mProgramModel = new QSqlTableModel( this, mSQLDatabase );
		mProgramModel->setTable( PROGRAM );
		mProgramModel->setEditStrategy( QSqlTableModel::OnManualSubmit );
		mProgramModel->select();

		mProgramModel->setHeaderData( 0, Qt::Horizontal, tr( "id" ) );
		mProgramModel->setHeaderData( 1, Qt::Horizontal, tr( "semester" ) );
		mProgramModel->setHeaderData( 2, Qt::Horizontal, tr( "disipline" ) );

		// Faculty
		query.exec( tr( "create table " ) +
			        FACULTY + 
					tr( " (id int primary key, name varchar(20))" ) );
		
		mFacultyModel = new QSqlTableModel( this, mSQLDatabase );
		mFacultyModel->setTable( FACULTY );
		mFacultyModel->setEditStrategy( QSqlTableModel::OnManualSubmit );
		mFacultyModel->select();

		mFacultyModel->setHeaderData( 0, Qt::Horizontal, tr( "id" ) );
		mFacultyModel->setHeaderData( 1, Qt::Horizontal, tr( "name" ) );

		// Room
		query.exec( tr( "create table " ) +
			        ROOM + 
					tr( " (id int primary key, name varchar(20), seats int, equipment varchar(20))" ) );
		
		mRoomModel = new QSqlTableModel( this, mSQLDatabase );
		mRoomModel->setTable( ROOM );
		mRoomModel->setEditStrategy( QSqlTableModel::OnManualSubmit );
		mRoomModel->select();

		mRoomModel->setHeaderData( 0, Qt::Horizontal, tr( "id" ) );
		mRoomModel->setHeaderData( 1, Qt::Horizontal, tr( "name" ) );
		mRoomModel->setHeaderData( 2, Qt::Horizontal, tr( "seats" ) );
		mRoomModel->setHeaderData( 3, Qt::Horizontal, tr( "equipment" ) );

		// Course
		query.exec( tr( "create table " ) +
			        COURSE + 
					tr( " (id int primary key, name varchar(20), books varchar(20), equipment varchar(20), software varchar(20), objectivies varchar(20))" ) );
		
		mCourseModel = new QSqlTableModel( this, mSQLDatabase );
		mCourseModel->setTable( COURSE );
		mCourseModel->setEditStrategy( QSqlTableModel::OnManualSubmit );
		mCourseModel->select();

		mCourseModel->setHeaderData( 0, Qt::Horizontal, tr( "id" ) );
		mCourseModel->setHeaderData( 1, Qt::Horizontal, tr( "name" ) );
		mCourseModel->setHeaderData( 2, Qt::Horizontal, tr( "books" ) );
		mCourseModel->setHeaderData( 3, Qt::Horizontal, tr( "equipment" ) );
		mCourseModel->setHeaderData( 4, Qt::Horizontal, tr( "software" ) );
		mCourseModel->setHeaderData( 5, Qt::Horizontal, tr( "objectivies" ) );

		// Schedule
		query.exec( tr( "create table " ) +
			        SCHEDULE + 
					tr( " (id int primary key, programId int, facultyId, roomId, courseId)" ) );
		
		mScheduleModel = new QSqlTableModel( this, mSQLDatabase );
		mScheduleModel->setTable( SCHEDULE );
		mScheduleModel->setEditStrategy( QSqlTableModel::OnManualSubmit );
		mScheduleModel->select();

		mScheduleModel->setHeaderData( 0, Qt::Horizontal, tr( "id" ) );
		mScheduleModel->setHeaderData( 1, Qt::Horizontal, tr( "program" ) );
		mScheduleModel->setHeaderData( 2, Qt::Horizontal, tr( "faculty" ) );
		mScheduleModel->setHeaderData( 3, Qt::Horizontal, tr( "room" ) );
		mScheduleModel->setHeaderData( 4, Qt::Horizontal, tr( "course" ) );
	}
}

Database::~Database()
{
}

void
Database::query( const QString& query )
{
	QSqlQuery q;
	q.exec( query );

	mProgramModel->select();
	mFacultyModel->select();
	mRoomModel->select();
	mCourseModel->select();
	mScheduleModel->select();
}

void
Database::submit()
{
	mProgramModel->database().transaction();
	if( mProgramModel->submitAll() )
	{
		mProgramModel->database().commit();
	}
	else
	{
		mProgramModel->database().rollback();
		QMessageBox::warning( NULL, tr( PROGRAM ), tr( "The database reported an error: %1" ) + mProgramModel->lastError().text() );
	}

	mFacultyModel->database().transaction();
	if( mFacultyModel->submitAll() )
	{
		mFacultyModel->database().commit();
	}
	else
	{
		mFacultyModel->database().rollback();
		QMessageBox::warning( NULL, tr( FACULTY ), tr( "The database reported an error: %1" ) + mFacultyModel->lastError().text() );
	}

	mRoomModel->database().transaction();
	if( mRoomModel->submitAll() )
	{
		mRoomModel->database().commit();
	}
	else
	{
		mRoomModel->database().rollback();
		QMessageBox::warning( NULL, tr( ROOM ), tr( "The database reported an error: %1" ) + mRoomModel->lastError().text() );
	}

	mCourseModel->database().transaction();
	if( mCourseModel->submitAll() )
	{
		mCourseModel->database().commit();
	}
	else
	{
		mCourseModel->database().rollback();
		QMessageBox::warning( NULL, tr( COURSE ), tr( "The database reported an error: %1" ) + mCourseModel->lastError().text() );
	}

	mScheduleModel->database().transaction();
	if( mScheduleModel->submitAll() )
	{
		mScheduleModel->database().commit();
	}
	else
	{
		mScheduleModel->database().rollback();
		QMessageBox::warning( NULL, tr( SCHEDULE ), tr( "The database reported an error: %1" ) + mScheduleModel->lastError().text() );
	}
}

void
Database::revert()
{
	mProgramModel->revertAll();
	mFacultyModel->revertAll();
	mRoomModel->revertAll();
	mCourseModel->revertAll();
	mScheduleModel->revertAll();

}